package wf3.filter;

import acceso.util.Escritor;
import acceso.util.LogueoHelper;
import acceso.util.UserSesion;
import acceso.util.WorkflowUtil;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import wf.dto.ContenedorDto;
import wf.dto.geo.CongeoDto;
import wf3.core.Configuration;
import wf3.core.bean.LoginBean;
import wf3.core.dao.GeovolutionDAO;
import wf3.core.dao.WorkflowDAO;
import wf3.core.manager.DAOFactory;
import wf3.util.EmptyContenedorDto;
import wf3.util.EmptyGeocontenedorDto;

/**
 *
 * @author Rómulo Galindo Tanta
 */
public class SessionFilter implements Filter {

    FilterConfig filterConfig = null;
    static String cookie_name = "";
    static String cookie_domain = "";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        Escritor.escribe_debug("[filtro: SessionFilter] [path: " + req.getRequestURI() + (req.getQueryString() != null ? "?" + req.getQueryString() : "") + "]");
        HttpSession ses = req.getSession();
        Cookie cookie = getCookie(req);
        UserSesion US = ses.getAttribute("US") != null ? (UserSesion) ses.getAttribute("US") : null;
        boolean logeado = ((US != null & cookie != null) && US.getId_sesion() == WorkflowUtil.convertir_entero(cookie.getValue()));
//        Escritor.escribe_debug("[sessionFileter] a) logeado:" + logeado + ", US:" + US);

        if (!logeado) {
            //Remover  parametro US
            ses.removeAttribute("US");
            if (cookie != null && LogueoHelper.loguear(req, WorkflowUtil.convertir_entero(cookie.getValue()))) {
                US = ses.getAttribute("US") != null ? (UserSesion) ses.getAttribute("US") : null;
                logeado = true;
            } else if (req.getParameter("usu") != null & req.getParameter("pwd") != null) {
                if (LogueoHelper.loguear(req)) {
                    US = ses.getAttribute("US") != null ? (UserSesion) ses.getAttribute("US") : null;
                    logeado = true;
                }
            }
        }
        Escritor.escribe_debug("[sessionFileter] b) logeado:" + logeado + ", US:" + US + "?" + req.getRequestURI());
        if (req.getRequestURI().contains("wf")) {
            ContenedorDto cnt = get_cnt(WorkflowUtil.convertir_entero(request.getParameter("co_conten"), -1), US != null ? US.getId_sesion() : 0);
            if (cnt == null) {//SI EL CONTENEDOR ES NULO
                if (US == null) {
                    res.sendRedirect("wl");
                } else {
                    cnt = new EmptyContenedorDto();
                    cnt.setCo_conten(-1);
                    cnt.addException(new Exception("No hay datos para el contenedor \"" + request.getParameter("co_conten") + "\""));
                    req.setAttribute("cnt", cnt);
                    chain.doFilter(request, response);
                }
            } else if (cnt.isIl_sesion()) {//SI EL CONTENEDOR NO ES NULO
                if (US == null) {//No existe session
                    request.setAttribute("url", "wf?" + req.getQueryString());
                    RequestDispatcher dispatcher = request.getRequestDispatcher("/login/login.jsp");
                    dispatcher.forward(request, response);
                } else if (US != null & !US.isIs_dummie()) {//existe todo
                    req.setAttribute("cnt", cnt);
                    chain.doFilter(request, response);
                } else {//si es dommie
                    //pide logearse
                    request.setAttribute("url", "wf?" + req.getQueryString());
                    RequestDispatcher dispatcher = request.getRequestDispatcher("/login/login.jsp");
                    dispatcher.forward(request, response);
                }
            } else {//SI EL CONTENEDOR NO ES NULO PERO ASU VES NO REQUIERE SESSION.
                if (US == null) {
                    Escritor.escribe_debug("[sessionFileter] A-1) cnt:" + cnt.isIl_sesion() + ", US:" + US);
                    LoginBean lb = new LoginBean();
                    lb.setUserAgent(req.getHeader("user-agent"));
                    ses.setAttribute("US", new UserSesion(lb.getNavegador()));
                    res.addCookie(new_cookie("0"));
                    req.setAttribute("cnt", cnt);
                    chain.doFilter(request, response);
                } else {
                    Escritor.escribe_debug("[sessionFileter] A-2) cnt:" + cnt.isIl_sesion() + ", US:" + US);
                    req.setAttribute("cnt", cnt);
                    chain.doFilter(request, response);
                }
            }
        } else if (req.getRequestURI().contains("wg") | req.getRequestURI().contains("wg2")) {
            Escritor.escribe_debug("[sessionFileter] a");
            CongeoDto gnt = get_gnt(WorkflowUtil.convertir_entero(request.getParameter("co_congeo"), -1), US != null ? US.getId_sesion() : 0);
            if (gnt == null) {//SI EL GEOCONTENEDOR ES NULO
                Escritor.escribe_debug("[sessionFileter] a1");
                if (US == null) {
                    res.sendRedirect("wl");
                } else {
                    //---------------**
                    gnt = new EmptyGeocontenedorDto();
                    gnt.setCo_congeo(-1);
                    gnt.getLsexc().add(new Exception("No hay datos para el contenedor \"" + request.getParameter("co_congeo") + "\""));
                    req.setAttribute("cnt", gnt);
                    //---------------**
                    chain.doFilter(request, response);
                }
            } else if (gnt.isIl_sesion()) {//SI EL CONTENEDOR NO ES NULO
                Escritor.escribe_debug("[sessionFileter] a2");
                if (US == null) {//No existe session
                    request.setAttribute("url", "wg?" + req.getQueryString());
                    RequestDispatcher dispatcher = request.getRequestDispatcher("/login/login.jsp");
                    dispatcher.forward(request, response);
                } else if (US != null & !US.isIs_dummie()) {//existe todo
                    req.setAttribute("cnt", gnt);
                    chain.doFilter(request, response);
                } else {//si es dommie
                    //pide logearse
                    request.setAttribute("url", "wg?" + req.getQueryString());
                    RequestDispatcher dispatcher = request.getRequestDispatcher("/login/login.jsp");
                    dispatcher.forward(request, response);
                }
            } else {//SI EL CONTENEDOR NO ES NULO PERO ASU VES NO REQUIERE SESSION.
                Escritor.escribe_debug("[sessionFileter] a3");
                if (US == null) {
                    Escritor.escribe_debug("[sessionFileter] A-1) cnt:" + gnt.isIl_sesion() + ", US:" + US);
                    LoginBean lb = new LoginBean();
                    lb.setUserAgent(req.getHeader("user-agent"));
                    ses.setAttribute("US", new UserSesion(lb.getNavegador()));
                    res.addCookie(new_cookie("0"));
                    req.setAttribute("cnt", gnt);
                    chain.doFilter(request, response);
                } else {
                    Escritor.escribe_debug("[sessionFileter] A-2) cnt:" + gnt.isIl_sesion() + ", US:" + US);
                    req.setAttribute("cnt", gnt);
                    chain.doFilter(request, response);
                }
            }
        }
    }

    private ContenedorDto get_cnt(int co_conten, int id_session) {
        WorkflowDAO dao = (WorkflowDAO) DAOFactory.get_workflowdao(id_session);
        ContenedorDto cnt = dao.getContenedorDto(co_conten);
        try {
            dao.CLOSE_SESSION();
        } catch (Exception ep) {
            Escritor.escribe_errors(ep.getMessage());
        }
        return cnt;
    }

    private CongeoDto get_gnt(int co_congeo, int id_session) {
        GeovolutionDAO dao = (GeovolutionDAO) DAOFactory.get_workflowgdao(id_session);
        CongeoDto cnt = dao.GET_CONGEO(co_congeo);
        try {
            dao.CLOSE_SESSION();
        } catch (Exception ep) {
            Escritor.escribe_errors(ep.getMessage());
        }
        return cnt;
    }

    public FilterConfig getFilterConfig() {
        return (this.filterConfig);
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig filterConfig) {
        Escritor.escribe_debug("Iniciando Filtro(SessionFilter)");
        this.filterConfig = filterConfig;
        cookie_name = ((Configuration) filterConfig.getServletContext().getAttribute("CFG")).getCookie_name();
        Escritor.escribe_debug("Filtro(SessionFilter) con cookie_name=" + cookie_name);
        cookie_domain = ((Configuration) filterConfig.getServletContext().getAttribute("CFG")).getCookie_domain();
        Escritor.escribe_debug("Filtro(SessionFilter) con cookie_domain=" + cookie_domain);
        Escritor.escribe_info("Filtro (SessionFilter) Iniciado");
    }

    public synchronized static void update_filter(String cn, String cd) {
        Escritor.escribe_debug("Actualizando Filtro(SessionFilter)");
        cookie_name = cn;
        Escritor.escribe_debug("Filtro(SessionFilter) actualizando cookie_name=" + cookie_name);
        cookie_domain = cd;
        Escritor.escribe_debug("Filtro(SessionFilter) actualizando cookie_name=" + cookie_domain);
        Escritor.escribe_info("Filtro (SessionFilter) Actualizado");
    }

    public Cookie new_cookie(String cook) {
        Cookie cookie = new Cookie(cookie_name, cook);
        cookie.setPath("/");
        cookie.setDomain(cookie_domain);
        cookie.setMaxAge(-1);
        return cookie;
    }

    public Cookie getCookie(HttpServletRequest req) {
        Cookie cookie = null;
        Cookie[] cookies = req.getCookies();
        if (cookies != null && cookies.length > 0) {
            try {
                for (Cookie ck : cookies) {
                    if (ck.getName().contentEquals(cookie_name) && !ck.getValue().isEmpty()) {
                        cookie = ck;
                        break;
                    }
                }
            } catch (Exception ep) {
                System.out.println(">>" + ep.getMessage());
            }
        }
        return cookie;
    }
}
